[wasm64] making JS bindings wasm64 aware - #12869
Conversation
| POINTER_SIZE: 4, | ||
| QUANTUM_SIZE: 4, | ||
| POINTER_SIZE: getPointerSize(), | ||
| POINTER_TYPE: MEMORY64 ? 'i64' : 'i32', |
There was a problem hiding this comment.
get you just call getPointerType() here?
There was a problem hiding this comment.
You mean pointerType() from parseTools.js ? Is that always available to this file? I am still unclear on how all these JS files fit together :)
There was a problem hiding this comment.
My understanding is that all of these files (modules.py, parseTools.js, runtime.js at least) all loaded together when processing JS so they all shared a single namespace.
There was a problem hiding this comment.
I tried, and I can't access variables from parseTools.js here, though I might be getting it wrong :)
sbc100
left a comment
There was a problem hiding this comment.
I don't fully grok the makeGetValue / makeSetValue stuff bit everything else looks good!
|
If you feel like splitting of the |
|
Is this still a draft? |
|
No, I'd rather not split that off.. and yes, still a draft until I get further along I think? |
This reflects changes in the function signature in https://reviews.llvm.org/D101985 and also uses `from64` function defined in emscripten-core#12869. This has not been tested against wasm64 yet and I'm uploading this mainly for discussions at this point. Also in the team chat of the tools team we discussed other alternatives to `from64` function, which can be done separately and not reflected here.
There are a lot of places where pointers get cast to int, and to prepare for further Memory64 changes, those are changed to long. I chose long since it is most similar to the existing int, instead of e.g intptr_t, since long is more universal (there are many cases where the actual data stored is not a pointer). Since under wasm32 int and long are equal, this should in theory be a NFC for wasm32, making it easier to review. It also allows #12869 to be smaller
|
The only tests failing are |
kripken
left a comment
There was a problem hiding this comment.
Nice progress!
Reading this, I had an idea. This PR does the best we can do currently in terms in JS code quality, but that still brings downsides - but we could avoid them by porting code from JS to C. This is actually what we're doing with the filesystem rewrite @ethanalee is working on now, which means that it might be best to wait for that to land. In fact once #15104 lands then we could say that MEMORY64 depends on WASMFS and then we'd be limited to stdout (for now) but we'd have less JS to need to worry about.
Similarly, perhaps we could all as a team make an effort to port other places with lots of from64 and other JS workarounds in this PR to C. That's generally the right direction anyhow, and the result would be more maintainable and optimizable, and would make this PR smaller and better. WDYT?
|
@kripken the reason I am trying to land this is because it is an enormous amount of work maintaining and testing it, so the prospect of waiting on a PR that is going to make yet more significant changes to this PR does not sound great to me. In fact, I'd like to land this with as few changes as possible, and leave any cleanup to future PRs, of which there will be many anyway. Most changes that make things worse are pretty isolated, like you said if we find a better way to do This PR should have very little effect on wasm32 and makes things strictly better for wasm64. The way BigInt was designed in JS makes it surprisingly hard to do this stuff non-intrusively. |
|
@aardappel I see, makes sense. I wouldn't oppose landing this soon, then. However, I think we should agree as a team on a plan for the code here, that ends up getting to a good place in the near future. |
| // have __heap_base hardcoded into it - it receives it from JS as an extern | ||
| // global, basically). | ||
| __heap_base: '{{{ HEAP_BASE }}}', | ||
| __heap_base: '{{{ to64(HEAP_BASE) }}}', |
There was a problem hiding this comment.
Why is this ok to remain as is and not use new WebAssembly.Global but the above ones are not?
There was a problem hiding this comment.
This was already not using new WebAssembly.Global before my change.. I have no idea why.
| implemented in javascript. | ||
| """ | ||
| command = config.NODE_JS + [filename] + jsargs | ||
| command = config.NODE_JS + ['--experimental-wasm-bigint'] + [filename] + jsargs |
There was a problem hiding this comment.
Is this needed for something?
There was a problem hiding this comment.
Yes, the JS tools themselves may now contain code that uses bigints?
There was a problem hiding this comment.
Is that something you have added in this PR? It seems odd that that would be needed just to process the library js code.. can you point to an example?
There was a problem hiding this comment.
I'd have to run 64-bit test for that again to uncover that. Can we leave it in? If it's just for the tools it doesn't hurt. Or if you insist I can put it in a comment so it is easier to re-apply when we return to fixing 64-bit issues.
| '-Wno-format', | ||
| '-nostdlib', | ||
| compiler_rt, | ||
| '-s', 'MEMORY64=' + str(settings.MEMORY64), |
There was a problem hiding this comment.
I don't think this will work. This gets run just once one first use so we don't want to depend on the settings use in that moment. If there are differences here then we would need a second set of json file and have them stored separately in the cache.
See generate_struct_info in emscripten.py.
There was a problem hiding this comment.
Ok, I guess I am not clear on how to fix this.. maybe we can discuss that offline. Or at least maybe I can just put a FIXME in there for when testing with wasm64 resumes.. so far this has worked in allowing tests to pass.
There was a problem hiding this comment.
The fix I think would be to have a different filename when running in 64bit mode. See:
Line 826 in bca56b3
It won't work as it stands because if you have previously built the struct_info.json with -sMEMORY64 and then try to build something without that flag .. it would use the wasm64 version of the json file.. and things be broken in horrible ways, right?
There was a problem hiding this comment.
Ok, so we need a generated_struct_info64.json ? I can look into how to set that up in a follow-up. I'll comment this out for now.
|
I mean you can put the quotes outside the `{{{ }}}` and just have
`POINTER_TYPE` inside.. avoiding the backticks (I think).
…On Mon, Oct 4, 2021 at 10:08 AM Wouter van Oortmerssen < ***@***.***> wrote:
***@***.**** commented on this pull request.
------------------------------
In src/runtime_safe_heap.js
<#12869 (comment)>
:
> @@ -14,7 +14,7 @@
@param {number|boolean=} noSafe */
function setValue(ptr, value, type, noSafe) {
type = type || 'i8';
- if (type.charAt(type.length-1) === '*') type = 'i32'; // pointers are 32-bit
+ if (type.charAt(type.length-1) === '*') type = {{{ `'${POINTER_TYPE}'` }}};
That would generate i32 and it needs to generate 'i32'
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#12869 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAD55ZN7ZXBWUFMAF3OIOP3UFHNPXANCNFSM4UAGXGBQ>
.
Triage notifications on the go with GitHub Mobile for iOS
<https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675>
or Android
<https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub>.
|
kripken
left a comment
There was a problem hiding this comment.
How about splitting out the strftime and webidl binder changes (so that if we end up bisecting it doesn't reach here)? Otherwise, I think this can stay in one PR.
| else: | ||
| benchmarkers += [ | ||
| # EmscriptenBenchmarker('Node.js', config.NODE_JS), | ||
| ] |
There was a problem hiding this comment.
Wasm64 does seem special enough to justify this, I think. And we do have a few other global params here like profiling etc.
| # separately in the cache. | ||
| # Whereever generated_struct_info.json is generated, there now | ||
| # needs to be a generated_struct_info64.json for MEMORY64 mode. | ||
| # '-s', 'MEMORY64=' + str(settings.MEMORY64), |
There was a problem hiding this comment.
I think we'd need a separate cache dir for memory64 (like for LTO), and to pass this tool a flag in that case, but I'm not sure.
There was a problem hiding this comment.
Yes, we discussed this should be fixed in a follow-up, see #15218 (and also elsewhere in this PR)
| *l = snprintf(*s, sizeof *s, "%+.2ld%.2ld", // XXX EMSCRIPTEN: %d => %ld | ||
| (tm->__tm_gmtoff)/3600, | ||
| abs(tm->__tm_gmtoff%3600)/60); | ||
| labs(tm->__tm_gmtoff%3600)/60); // XXX EMSCRIPTEN: abs => labs |
There was a problem hiding this comment.
Maybe better to disable that warning rather than hack musl like this. See:
emscripten/tools/system_libs.py
Lines 682 to 688 in dfb2d09
Also, it looks like this was removed upstream so this issue will go away once I get around to landing #13006: https://github.com/emscripten-core/musl/
| set_env('EMTEST_REBASELINE', options.rebaseline) | ||
| set_env('EMTEST_VERBOSE', options.verbose) | ||
| set_env('EMTEST_CORES', options.cores) | ||
| set_env('EMTEST_FORCE64', options.force64) |
There was a problem hiding this comment.
This still needs to be resolved.. we shouldn't need the global keyword above.
| else: | ||
| benchmarkers += [ | ||
| # EmscriptenBenchmarker('Node.js', config.NODE_JS), | ||
| ] |
There was a problem hiding this comment.
@kripken WDYT about these changes to test_benchmark.py
|
@sbc100 benchmark changes look good to me. They aren't temporary changes, but a new mode for the runner. Makes sense to commit them I think. |
|
Two more:
|
kripken
left a comment
There was a problem hiding this comment.
Ok, if you'd rather do the getPointerSize() etc. stuff in a followup, that seems ok to me.
| else: | ||
| benchmarkers += [ | ||
| # EmscriptenBenchmarker('Node.js', config.NODE_JS), | ||
| ] |
There was a problem hiding this comment.
+1 from me for these changes to benchmarking.
This regressed in #12869 - while adding wasm64 support we reordered how the args are added. The extra emcc args must be at the end so that they apply on top of the other ones, in particular, some tests must disable minimal runtime.
This regressed in emscripten-core#12869 - while adding wasm64 support we reordered how the args are added. The extra emcc args must be at the end so that they apply on top of the other ones, in particular, some tests must disable minimal runtime.
This is a large collection of fixes resulting from trying to run the tests under wasm64. It is not complete, i.e. does not pass all tests, and requires a specific local setup. It is unknown how much work is left to pass all of them, though this allows significant amount of code to work.
I am trying to land these changes, because, well, maintaining this large fork is getting onerous, and it would be beneficial for wasm64 related changes to be already present, even if not used.
This PR has the wasm64 tests OFF, meaning it is meant to be a NFC for wasm32, effectively.
Of course, this PR contains a lot of unrelated fixes that ideally could have been spread out over 10+ PRs, had I known what I was doing. I think it made sense to initially collect all these changes in one PR, since it was hard to tell what shape things would take, and in fact there have been large sweeping changes that I later undid, which we've now all been saved from.
The question remains, should this PR be split up, and if so, in how many PRs? I would request to not go too crazy on this, this will not be a neat PR no matter how you slice it. Then there's of course the issue that there may be dependencies.
Follow-up to the work in #12658 and #14613